import tools from "../tools"

export default class ZSetList extends Element {
    constructor() {
        super()
        document.on("key-change", (evt) => {
            this.key = evt.data.key
            window.redis_key = evt.data.key
            this.fetchZSetList()
        })
        document.on("zset-refresh", () => {
            this.fetchZSetList()
        })
        document.on("zset-search", evt => {
            this.searchZSetData(evt.data.key)
        })
    }

    componentDidMount() {
        this.fetchZSetList()
    }

    searchZSetData(pattern) {
        if (!pattern) {
            return this.fetchZSetList()
        }
        setTimeout(()=>{
            tools.xcall("async_z_set_list", window.redis_key, pattern, res => {
                if (res.code === 200) {
                    this.keyList = res.data
                    this.componentUpdate()
                } else {
                    tools.alert(res.msg, {"type": "error"})
                }
            })
        })
    }

    fetchZSetList() {
        setTimeout(()=>{
            tools.xcall("async_z_set_list", window.redis_key, "*", res => {
                this.keyList = res.data || []
                this.componentUpdate()
            })
        })
    }

    keyList = []


    // scroll down
    appendElements(index, n) {
        if (index === undefined) index = 0
        let elements = []
        for (let i = 0; i < n; ++i, ++index) {
            if (index >= this.totalItems()) break
            let item = this.itemAt(index)
            elements.push(this.renderItem(item, index))
        }
        this.append(elements)
        return {moreafter: (this.totalItems() - index)} // return estimated number of items below this chunk
    }

    // scroll up
    prependElements(index, n) {

        if (index === undefined) index = this.totalItems() - 1
        let elements = []
        for (let i = 0; i < n; ++i, --index) {
            if (index < 0) break
            let item = this.itemAt(index)
            elements.push(this.renderItem(item, index))
        }
        elements.reverse()
        this.prepend(elements)
        return {morebefore: (index < 0 ? 0 : index + 1)} // return estimated number of items above this chunk
    }

    // scroll to
    replaceElements(index, n) {
        let elements = []
        let start = index
        for (let i = 0; i < n; ++i, ++index) {
            if (index >= this.totalItems()) break
            let item = this.itemAt(index)
            elements.push(this.renderItem(item, index))
        }
        this.patch(elements)
        return {
            morebefore: start <= 0 ? 0 : start,
            moreafter: this.totalItems() - index
        }
    }

    // sciter virtual-list content load function
    oncontentrequired(evt) {
        let {length, start, where} = evt.data
        if (where > 0) evt.data = this.appendElements(start, length)  // scrolling down, need to append more elements
        else if (where < 0) evt.data = this.prependElements(start, length) // scrolling up, need to prepend more elements
        else evt.data = this.replaceElements(start, length) // scrolling to index
        return true
    }

    // sciter virtual-lis function
    itemAt(at) {
        return this.keyList[at]
    }

    // sciter virtual-lis function
    totalItems() {
        return this.keyList.length || 0
    }

    // sciter virtual-lis function
    indexOf(item) {
        return this.keyList.indexOf(item)
    }

    /**
     * 执行复制功能
     * @param val
     */
    doCopy(val) {
        Clipboard.writeText(val)
    }

    /**
     * 渲染虚拟列表的每一行
     * @param item {string|Object} key或者命名空间对象
     * @param index {number} 索引
     * @returns {JSX.Element|*}
     */
    renderItem(item, i) {
        return <div class="tr" key={i}>
            <div class="td v v-field">
                <div class="r-v">{item.key}</div>
                <div class="key-copy" onClick={() => this.doCopy(item.key)}>复制</div>
            </div>
            <div class="td k">
                <div class="r-v">{item.value}</div>
                <div class="key-copy" onClick={() => this.doCopy(item.value)}>复制</div>
            </div>
            <div class="td v v-a">
                <div class="btn" onClick={() => {
                    setTimeout(() => {
                        let [x, y] = tools.windowPosition()
                        let [w, h] = tools.windowSize()
                        let scale = devicePixelRatio
                        let width = 320 * scale
                        let height = 200 * scale
                        let modal = tools.getView().modal({
                            width,
                            height,
                            x: x + w / 2 - width  / 2,
                            y: y + h / 2 - height / 2,
                            url: "/redis/edit_zset_value.html",
                            parameters: {
                                title: "修改zset的值",
                                view: tools.getView(),
                                key: window.redis_key,
                                field: item.key,
                                value: item.value
                            }
                        })
                        if (modal.status === true) {
                            this.fetchZSetList()
                        }
                    })
                }}>修改
                </div>
                <div class="btn" onClick={() => {
                    tools.confirm("确定要删除吗？")
                        .then(res => {
                            if (res === true) {
                                tools.xcall("async_rem_z_set_member", window.redis_key, item.key, res => {
                                    if (res.data === true) {
                                        return tools.alert("删除成功！", {type: "success"})
                                            .then(() => {
                                                this.fetchZSetList()
                                            })
                                    }
                                    tools.alert("删除失败！", {type: "error"})
                                })
                            }
                        })
                }}>删除
                </div>
            </div>
        </div>
    }


    render() {
        return <div class="set-v-list">
            {this.renderVirtualList()}
        </div>
    }

    renderVirtualList() {
        let list = []
        if (this.vlist) {
            let firstIndex = this.vlist.firstBufferIndex
            let lastIndex = this.vlist.lastBufferIndex
            let firstVisibleIndex = this.vlist.firstVisibleItem?.elementIndex || 0
            let lastVisibleIndex = this.vlist.lastVisibleItem?.elementIndex || lastIndex
            let totalItems = this.totalItems()
            if (firstVisibleIndex == 0)
                this.post(() => {
                    this.vlist && this.vlist.navigate("start")
                })
            else if (lastVisibleIndex >= totalItems) // number of items reduced so buffer is past total count
                this.post(() => {
                    this.vlist && this.vlist.navigate("end")
                })
            else if (this.vlist.itemsTotal != totalItems) { // number of items reduced, update scroll
                lastIndex = firstIndex + Math.min(totalItems, this.vlist.slidingWindowSize) - 1
                this.post(() => {
                    this.vlist.itemsAfter = totalItems - this.vlist.itemsBefore - this.children.length
                })
            }
            for (let index = firstIndex; index <= lastIndex; ++index) {
                let item = this.itemAt(index)
                if (item) list.push(this.renderItem(item, index))
            }
        }
        return list
    }
}